﻿using Microsoft.AspNetCore.Mvc;
using SocketGateway.DTO;
using System.Text.Json;
using System.Text.Json.Serialization;
using TK.TSocket;

namespace SocketGateway
{
    /// <summary>
    /// startup
    /// </summary>
    public static class Startup
    {
        /// <summary>
        /// 注入服务
        /// </summary>
        public static void AddServiceCore(this IServiceCollection services)
        {
            services.AddMemoryCache();
            services.AddSingleton<ITcpSocketServer, TcpSocketServer>(sp => new TcpSocketServer(InitSokcetConfigFile));
            services.AddSingleton<IReceiveData, ReceiveData>();
            services.AddMvc().AddJsonOptions(jsonOption =>
            {
                jsonOption.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
                jsonOption.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
                jsonOption.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString;
            }).ConfigureApiBehaviorOptions(option =>
            {
                option.InvalidModelStateResponseFactory = context =>
                {
                    var result = new BaseResultDto { Code = 405, Msg = string.Join('|', context.ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage))) };
                    return new ObjectResult(result);
                };
            });
            services.AddCors(corOption =>
            {
                corOption.AddDefaultPolicy(policyBuidler =>
                {
                    policyBuidler.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
                });
            });
            services.AddHostedService<MyHostedService>();
        }

        /// <summary>
        /// 注册中间件
        /// </summary>
        public static void UseMiddlewareCore(this IApplicationBuilder app)
        {
            app.UseFileServer();
            app.UseMiddleware<ExceptionMiddleware>();
            app.UseCors();
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
            });
        }

        #region private methods
        /// <summary>
        /// socket 初始化文件数据
        /// </summary>
        private static void InitSokcetConfigFile(TcpSocketServerConfig tcpConfig)
        {
            var baseDir = Path.Combine(AppContext.BaseDirectory, "DataConfig");
            Directory.CreateDirectory(baseDir);
            //黑白名单
            var path = Path.Combine(baseDir, "white_black_acl.json");
            if (File.Exists(path))
            {
                var whiteBlack = Tool.ToolHelper.JsonToObj<WhiteBlackDto>(path);
                if (whiteBlack != null)
                {
                    if (whiteBlack.IpWhiteList?.Any() == true)
                        tcpConfig.IpWhiteList.AddRange(whiteBlack.IpWhiteList.Where(m => !string.IsNullOrWhiteSpace(m)));
                    if (whiteBlack.IpBlackList?.Any() == true)
                        tcpConfig.IpBlackList.AddRange(whiteBlack.IpBlackList.Where(m => !string.IsNullOrWhiteSpace(m)));
                }
            }

            //socket监听
            path = Path.Combine(baseDir, "listener.json");
            if (File.Exists(path))
            {
                var listener = Tool.ToolHelper.JsonToObj<Dictionary<string, List<string>>>(path);
                if (listener != null && listener.ContainsKey("listener"))
                {
                    var data = listener["listener"];
                    if (data?.Any() == true)
                    {
                        data.ForEach(m => { tcpConfig.IpHostList.Add(new TouchSocket.Sockets.IPHost(m)); });
                    }
                }
            }
        }
        #endregion
    }
}
